﻿using MgSoft.Exceptions;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MgSoft.Configure
{

    public class FileConfigService : IConfigService
    {
        private string _appPatch;
        public const string DefaultConfigName = "AppConfig.json";
        private Dictionary<string,object> cache=new Dictionary<string, object>();

        private readonly object iLock = new object();

        public string AppPatch
        {
            get
            {
                if (string.IsNullOrEmpty(_appPatch))
                {
                    _appPatch = AppDomain.CurrentDomain.BaseDirectory;
                }
                return _appPatch;
            }
        }
        public T GetConfig<T>(string configName = DefaultConfigName) where T : class, new()
        {
            try
            {
                configName = string.IsNullOrEmpty(configName) ? DefaultConfigName : configName;

                if (cache.ContainsKey(configName)) return cache[configName] as T;

                string configFullName = GetConfigFileFullName(configName);

                if (!File.Exists(configFullName))
                {
                    throw new NoConfigurationExcetion();
                }
                return JsonConvert.DeserializeObject<T>(File.ReadAllText(configFullName));
            }
            catch (Newtonsoft.Json.JsonReaderException ex)
            {
                throw new Exception($@"请联系系统管理员。配置文件Json反序列化失败：{ex.Message}");
            }
            catch (NoConfigurationExcetion ex)
            {
                throw new NoConfigurationExcetion("请先完善系统配置信息");
            }
            catch (Exception ex)
            {
                throw new Exception($@"请联系系统管理员。遇到不可思议的错误：{ex.Message}");
            }
        }
        public void SetConfig<T>(T config, string configName = DefaultConfigName)
        {
            lock (iLock)
            {
                File.WriteAllText(GetConfigFileFullName(DefaultConfigName), JsonConvert.SerializeObject(config));
                SetCahce(config, configName);
            }
        }
        private string GetConfigFileFullName(string fileName)
        {
            return Path.Combine(AppPatch,fileName);
        }

        private void SetCahce(object config,string configName)
        {
            cache[configName] = config;
        }
    }
}
